#pragma once

#include <iostream>
#include <string>
#include <functional>
using std::string;

template<class T>
using func_t = std::function<void(T&)>;

// 线程的封装
template<class T>
class Thread
{
    public:
    Thread(func_t<T> func, const string& threadname,T& data)
    :_tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
    {}
    ~Thread()
    {}

    static void* ThreadRoutine(void* args)// 类内方法会隐藏一个this参数，所以要写成static
    {
        Thread* ts = static_cast<Thread*>(args);
        (void)args;// 防止编译器有告警
        ts->_func(ts->_data);
        return nullptr;
    }
    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if( n == 0) 
        {
            _isrunning = true;
            return true; // 创建成功
        }
        else return false;
    }
    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid, nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }
    bool IsRunning()
    {
        return _isrunning;
    }
    string ThreadName()
    {
        return _threadname;
    }
private:
    pthread_t _tid;
    string _threadname;
    bool _isrunning;
    func_t<T> _func; 
    T _data;
};